<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .small_box {
            width: 350px;
            height: 350px;
            /* float: left; */
            position: absolute;
            left: 200px;top: 50px;
        }

        .small_box img {
            width: 350px;
            height: 350px;
        }

        .small_box span {
            background: rgba(200, 200, 200, 0.5);
            position: absolute;
            left: 0;
            top: 0;
            display: none;
        }

        .small_box em {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            z-index: 1;
        }

        .big_box {
            width: 350px;
            height: 350px;
            /* float: left; */
            overflow: hidden;
            display: none;
            position: absolute;
            left: 600px;top: 50px;
        }

        .big_box img {
            width: 800px;
            height: 800px;
            position: absolute;
        }
    </style>
</head>
    <!-- 图片需要设置脱离文档流，最后通过定位定在相应的位置 -->
<body>
    <div class="small_box">
        <img src="https://img2.baidu.com/it/u=3355464299,584008140&fm=26&fmt=auto&gp=0.jpg" alt="">
        <span></span>
        <em></em>
    </div>
    <div class="big_box">
        <img src="https://img2.baidu.com/it/u=3355464299,584008140&fm=26&fmt=auto&gp=0.jpg" alt="">
    </div>
</body>
<script>
    // OOA：放大镜：等比例跟随移动
    // 1. 获取元素
    // 2. 绑定事件
    // 进入
    // 3. 显示，遮罩层，大图
    // 补全布局
    // 离开
    // 4. 隐藏，遮罩层，大图
    // 移动
    // 5. 遮罩层跟随鼠标移动
    // 根据遮罩层移动的距离计算比例
    // 根据比例计算右侧大图的移动距离

    // 向日葵班，总人数有45人，大扫除，出20人参与
    // 要求：玫瑰班，总67人，按照向日葵班的比例，出对应人数参与大扫除
    // var bili = 20 / 45
    // console.log(bili * 67)

    // OOD
    // class Magnifier{
    //     constructor(){
    //         // 获取元素
    //         // ...
    //         // 执行补全布局
    //         // 执行绑定事件
    //     }
    //     init(){
    //         // 补全布局
    //     }
    //     addEvent(){
    //         // 绑定事件
    //         // 进入
    //             // 执行显示
    //         // 离开
    //             // 执行隐藏
    //         // 移动
    //             // 执行移动
    //     }
    //     show(){
    //         // 显示
    //     }
    //     hide(){
    //         // 隐藏
    //     }
    //     move(){
    //         // 移动
    //         // 遮罩层跟随鼠标移动
    //         // 根据遮罩层移动的距离计算比例
    //         // 根据比例计算右侧大图的移动距离
    //     }
    // }

    // OOP
    class Magnifier {
        constructor() {
            // 获取元素
            this.sBox = document.querySelector(".small_box");
            this.sSpan = document.querySelector(".small_box span");
            this.bBox = document.querySelector(".big_box");
            this.bImg = document.querySelector(".big_box img");
            // 执行绑定事件
            this.addEvent();
        }
        addEvent() {
            const that = this;
            // this.sBox.onmouseover    会触发事件冒泡
            // this.sBox.onmouseenter    不会触发事件冒泡
            this.sBox.onmouseenter = function () {
                // 执行显示
                that.show();
            }
            // 离开
            this.sBox.onmouseleave = function () {
                // 执行隐藏
                that.hide();
            }
            // 移动
            this.sBox.onmousemove = function (eve) {
                const e = eve || window.event;
                // 利用布局，让鼠标不会移动到span身上
                const pos = {
                    x: e.offsetX,
                    y: e.offsetY
                };
                // 执行移动
                that.move(pos);
            }
        }
        show() {
            console.log(11)
            this.bBox.style.display = "block";
            this.sSpan.style.display = "block";

            // 执行补全布局
            this.init();
        }
        hide() {
            this.sSpan.style.display = "none";
            this.bBox.style.display = "none";
        }
        move(aaa) {
            // 【注】接受的参数的命名随意
            // 计算鼠标移动的真实位置
            let l = aaa.x - this.sSpan.offsetWidth / 2;
            let t = aaa.y - this.sSpan.offsetHeight / 2;
            // 边界限定
            if (l < 0) l = 0;
            if (t < 0) t = 0;
            if (l > this.sBox.offsetWidth - this.sSpan.offsetWidth) {
                l = this.sBox.offsetWidth - this.sSpan.offsetWidth;
            }
            if (t > this.sBox.offsetHeight - this.sSpan.offsetHeight) {
                t = this.sBox.offsetHeight - this.sSpan.offsetHeight;
            }
            // 遮罩层跟随鼠标移动
            this.sSpan.style.left = l + "px";
            this.sSpan.style.top = t + "px";
            // 根据遮罩层移动的距离计算比例
            const x = l / (this.sBox.offsetWidth - this.sSpan.offsetWidth);
            const y = t / (this.sBox.offsetHeight - this.sSpan.offsetHeight);
            // 根据比例计算右侧大图的移动距离
            this.bImg.style.left = x * (this.bBox.offsetWidth - this.bImg.offsetWidth) + "px";
            this.bImg.style.top = y * ( this.bBox.offsetHeight - this.bImg.offsetHeight) + "px";
        }
        init() {
            this.sSpan.style.width = this.bBox.offsetWidth / this.bImg.offsetWidth * this.sBox.offsetWidth + "px";
            this.sSpan.style.height = this.bBox.offsetHeight / this.bImg.offsetHeight * this.sBox.offsetHeight + "px";
        }
    }
    new Magnifier();


    // 【注】在什么时候补全事件，需要根据需求
            // DOM元素在css中被设置成了display:none;那么在js中无法获取该元素的信息
</script>

</html>